#ifndef SCENE_H
#define SCENE_H

#include "..//Math/Tuple3.h"
#include "..//Math/CommonMath.h"
#include "..//Math/CommonStruct.h"
#include "./StaticMesh.h"
#include ".//Lights//Lights.h"
//#include <vector>

#ifdef _cplusplus
extern "C"
{
#endif
bool InitCUDA(void);
#ifdef _cplusplus
}
#endif

#ifdef _cplusplus
extern "C"
{
#endif
void InitScene();
#ifdef _cplusplus
}
#endif

#ifdef _cplusplus
extern "C"
{
#endif
void RasterAllTriangles();
#ifdef _cplusplus
}
#endif

#ifdef _cplusplus
extern "C"
{
#endif
void ProcessLighting();
#ifdef _cplusplus
}
#endif

#ifdef _cplusplus
extern "C"
{
#endif
void RealseScene();
#ifdef _cplusplus
}
#endif

#ifdef _cplusplus
extern "C"
{
#endif
	void DumpRes(const char* pFileName, const unsigned char* pData, int DataSize);
#ifdef _cplusplus
}
#endif

#ifdef _cplusplus
extern "C"
{
#endif
	const cudaDeviceProp& GetDeviceProp();
#ifdef _cplusplus
}
#endif

#define MaxBounceCount 20
struct CRenderConfig
{
	int BounceCount;
	int ShadowRayCount;
	int SampleDirCount;
	float BounceCoeff[MaxBounceCount];
	_HOST_DEVICE_ CRenderConfig()
	{
		SampleDirCount = 121;
		BounceCount = 2;
		ShadowRayCount = 1;
		BounceCoeff[0] = 1.0f;
		BounceCoeff[1] = 1.0f;
		BounceCoeff[2] = 1.0f;
		BounceCoeff[3] = 1.0f;
		BounceCoeff[4] = 1.0f;
		BounceCoeff[5] = 1.0f;
		BounceCoeff[6] = 1.0f;
		BounceCoeff[7] = 1.0f;
		BounceCoeff[8] = 1.0f;
		BounceCoeff[9] = 1.0f;
		BounceCoeff[10] = 1.0f;
		BounceCoeff[11] = 1.0f;
		BounceCoeff[12] = 1.0f;
		BounceCoeff[13] = 1.0f;
		BounceCoeff[14] = 1.0f;
		BounceCoeff[15] = 1.0f;
		BounceCoeff[16] = 1.0f;
		BounceCoeff[17] = 1.0f;
		BounceCoeff[18] = 1.0f;
		BounceCoeff[19] = 1.0f;
	}
};

class CSceneManager
{
public:
	CRenderConfig								RenderConfig;
public:
	std::vector<CPointLight>					PointLights;
	std::vector<CDirectionalLight>				DirectionalLights;
	std::vector<CSpotLight>						SpotLights;
	std::vector<CStaticMeshInfoData>			StaticMeshData;
public:
	std::vector<CStaticMesh*>					SceneStaticMeshes;
	std::vector<RasterBufferElement*>			SceneRasterBufferElement;
	std::vector<RasterBufferElement*>			d_SceneRasterBufferElement;
	std::vector<unsigned char*>					d_LightMaps;
public:
	CVertex*									pd_VertexBuffer;
	int*										pd_VertexIndexBuffer;
	int*										pd_KDTreeTriangleIndexBuffer;
	int											KDopNodesCount;
	CKDopNode*									pd_KDopNodes;
	//should use constant memory
	int*										pd_ConstantData;
	//host
	int											VertexCount;
	int											VertexIndexCount;
	int											KDTreeTriangleIndexCount;

	CVertex*									ph_VertexBuffer;
	int*										ph_VertexIndexBuffer;
	int*										ph_KDTreeTriangleIndexBuffer;
	CKDopNode*									ph_KDopNodes;

	int											UsedVertexIndexTextureCount;
	int											UsedTriangleIndexTextureCount;
	int*										pd_VertexIndexTexture[10];
	int*										pd_TriangleIndexTexture[10];

	void										PrepareDeviceData();

	void										BuildCollisionData();

	void										LoadStaticMesh();

	void										RasterAllTriangles();

	void										BuildLighting();

	void										ReleaseHostData();
	
	void										ReleaseDeviceData();

	void										DumpLightMaps();

	void										PaserSceneFile(const std::string& FilePath);

	void										PrepareConstantData();

	void										SetupSampleDir();

	void										PrepareTextureBuffer();
	void										ReleaseTextures();

	CSceneManager();
};


#endif